1. PREPARE

During the second week of each unit, we’ll “walk through” a basic research workflow, or data analysis process, modeled after the Data-Intensive Research Workflow from Learning Analytics Goes to School (Krumm et al., 2018):

Figure 2.2 Steps of Data-Intensive Research Workflow

Each walkthrough will focus on a basic analysis guided by the social network perspective.

This week, our focus will be on preparing relational data for analysis, looking at some basic network stats, and creating a network visualization that helps illustrate key findings. Specifically, the Unit 1 Walkthrough will cover the following workflow topics:

  1. Prepare: Prior to analysis, we’ll take a look at the context in which are data is derived, you’re working with so you can formulate useful and answerable questions. You’ll also need to set up a “Project” for our Unit 1 walkthrough.

  2. Wrangle: Wrangling data entails the work of manipulating, cleaning, transforming, and merging data. In section 2 we focus on reading, reducing, and tidying our data.

  3. Explore: In section 3, we use simple summary statistics, more sophisticated approaches like term frequency-inverse document frequency (tf-idf), and basic data visualization to explore our data and see what insight it provides in response to our question.

  4. Model: While we won’t investigate approaches to Model our data until Unit 3 when we learn about community detection algorithms and exponential random graph models (ERGM), we will see how modeling has been applied.

  5. Communicate:

1a. Review the Research

Prior to analysis, it’s critical to understand the context and data sources available so you can formulate useful questions that can be feasibly addressed by your data. For this section, we’ll focus on the following topics:

In Social Network Analysis and Education: Theory, Methods & Applications, Carolyn (2013) notes that:

the social network perspective is one concerned with the structure of relations and the implication this structure has on individual or group behavior and attitudes

More specifically, Carolyn cites the following four features used by Freeman (2004) to define the social network perspective:

  1. Social network analysis is motivated by a relational intuition based on ties connecting social actors.

  2. It is firmly grounded in systematic empirical data.

  3. It makes use of graphic imagery to represent actors and their relations with one another.

  4. It relies on mathematical and/or computational models to succinctly represent the complexity of social life.

For Unit 1, our walkthrough will be guided by previous research and evaluation work conducted by the Friday Institute for Educational Innovation as part of the Massively Open Online Courses for Educators (MOOC-Ed) initiative.

A Social Network Perspective in MOOC-Eds

Kellogg, S., Booth, S., & Oliver, K. (2014). A social network perspective on peer supported learning in MOOCs for educatorsInternational Review of Research in Open and Distributed Learning15(5), 263-289.

Research Context

In the spring of 2013, The Friday Institute launched the MOOC-Ed Initiative to explore the potential of delivering personalized, high-quality professional development to educators at scale (Kleiman et al., 2013). In collaboration with the Alliance for Excellent Education, the Friday Institute launched this initiative with a 6-week pilot course called Planning for the Digital Learning Transition in K-12 Schools (DLT 1), which was offered again in September 2013 (DLT 2). This course was designed to help school and district leaders plan and implement K-12 digital learning initiatives.

Academics, as well as pundits from traditional and new media, have raised a number of concerns about MOOCs, including the lack of instructional and social supports. Among the core design principles of MOOC-Eds are collaboration and peer-supported learning. It is an assumption of this study that challenges arising form this problem of scale can be addressed by leveraging these massive numbers to develop robust online learning communities.

This mixed-methods case study used both SNA and qualitative methods to better understand peer support in MOOC-Eds through an examination of the characteristics, mechanisms, and outcomes of peer networks. Findings from this study demonstrate that even with technology as basic as a discussion forum, MOOCs can be leveraged to foster these networks and facilitate peer-supported learning. Although this study was limited to two unique cases along the wide spectrum of MOOCs, the methods applied provide other researchers with an approach for better understanding the dynamic process of peer supported learning in MOOCs.

Data Sources

MOOC-Ed registration form. All participants completed a registration form for each MOOC-Ed course. The registration form consists of self-reported demographic data, including information related to their professional role and work setting, years of experience in education, and personal learning goals.

MOOC-Ed discussion forums. All peer interaction, including peer discussion, feedback, and reactions (e.g., likes), take place within the forum area of MOOC-Eds, which are powered by Vanilla Forums. Because of the specific focus on peer supported learning, postings to or from course facilitators and staff were removed from the data set. Finally, analyses described below exclude more passive forms of interactions (i.e., read and reaction logs), and include only postings among peers.

For our Unit 1 walkthrough, we’ll take a look at data from the original Digital Learning Transition in K-12 Schools (DLT 1) which was not included in this study so we can make comparisons in our analysis to the DLT 2 course reported in this study. Also, for your independent analysis, you may want to consider working with the DLT 2 data to see if you can replicate some of the findings from this paper!

Your Turn

Take a quick look at the Description of the Dataset section from the Massively Open Online Course for Educators (MOOC-Ed) network dataset BJET article, as well as the accompanying data sets that we’ll be using for this walkthrough stored on Harvard Dataverse.

In the space below, type a brief response to the following questions:

  1. What were some of the steps necessary to construct this dataset?

  2. Name two “node attributes” from the dataset that might be useful for predicting participants who may be more engaged or central to the network? Why did you select those two?

  3. What else do you notice/wonder about this dataset?

1b. Identify Research Questions

A Social Network Perspective on Peer Supported Learning in MOOC-Eds was framed by three primary research questions related to peer supported learning:

  1. What are the patterns of peer interaction and the structure of peer networks that emerge over the course of a MOOC-Ed?

  2. To what extent do participant and network attributes (e.g., homophily, reciprocity, transitivity) account for the structure of these networks?

  3. To what extent do these networks result in the co-construction of new knowledge?

For our very first walkthrough, we are going to focus exclusively on RQ1 from the original study. Our question of interest is focused on very basic questions about our educator network:

How, and to what extent, did educators engage with other participants in the discussion forums?

Your Turn

Based on our course readings and your self-selected readings, what subquestions, or more specific research questions, might ask that help you answer the broader question we’ll be focused on for this walkthrough?

In the space below, type a brief response to the following questions:

-

1c. Check Packages

As highlighted in Chapter 6 of Data Science in Education Using R (DSIEUR):

Packages are shareable collections of R code that can contain functions, data, and/or documentation. Packages increase the functionality of R by providing access to additional functions to suit a variety of needs.

Let’s check to see which packages have already been loaded into our RStudio Cloud workspace. Take a look at the the Files, Plots, & Packages Pane in the lower right hand corner of RStudio Cloud to make sure these packages have been installed and loaded:

You should see some familiar tidytext packages from our Getting Started Walkthrough like {dplyr} and {readr} which we’ll be using again shortly. You should also see an important package call {igraph} that will rely on heavily for our network analyses.

If you are working in RStudio Desktop, or notice that the packages have not been installed and/or loaded, run the following install.packages() function code to install the {tidyverse} and {igraph} packages:

install.packages("tidyverse")
install.packages("igraph") 

And library() function to load them:

library(tidyverse)
library(igraph)

igraph 📦

At the end of this week, I’ll ask that you share with me your r script as evidence that you have completed the walkthrough. Although I highly recommend that that you manually type the code shared throughout this walkthrough, for large blocks of text it may be easier to cut and paste.


2. WRANGLE

In general, data wrangling involves some combination of cleaning, reshaping, transforming, and merging data (Wickham & Grolemund, 2017). The importance of data wrangling is difficult to overstate, as it involves the initial steps of going from the raw data to a dataset that can be explored and modeled (Krumm et al, 2018).

For our data wrangling this week, we’re keeping it simple since working with network data is a bit of a departure from our working with rectangular data frames. Our primary goals for Unit 1 are learning how to:

  1. Import Data. Before working with data, we need to “read” it into R and once imported, we’ll take at different ways to view our data in R.

  2. Create a Network Object.

  3. Simplify Network. Finally, we’ll learn about a handy simplify() function in the {igraph} package for removing ties that .

2a. Import Data

The Edge-List Format

To get started, we need to import, or “read”, our data into R. The function used to import your data will depend on the file format of the data you are trying to import, but R is pretty adept at working with many files types.

Take a look in the data folder in your Files pane. You should see the following .csv files:

  • dlt1-edgelist.csv

  • dlt1-nodes.csv

As its name implies, the first file dlt1-edgelist.csv is an edge-list that contains information about each tie, or relation between two actors in a network. In this context, a “tie” is a reply by one participant in the discussion forum to the post of another participant - or in some cases to their own post! These ties between a single actor are called “self-loops” and as we’ll see later in this section, igraph has a special function to remove these self loops from a sociogram, or network visualization.

The edge-list format is slightly different than other formats you have likely worked with before in that the values in the first two columns each row represent a dyad, or tie between two nodes in a network. An edge-list can also contain other information regarding the strength or duration of the relationship, sometime called “weight”, in addition to other “edge attributes.”

In addition to

  • Sender = Unique identifier of author of comment

  • Receiver = Unique identifier of identified recipient of comment

  • Timestamp = Time comment was posted

  • Parent = Primary category or topic of thread

  • Category = Subcategory or subtopic of thread

  • Thread_id = Unique identifier of a thread

  • Comment_id = Unique identifier of a comment\

Let’s use the read_csv() function from the {readr} package introduced in the Getting Started walkthrough to read in our edge-list and print the new ties data frame:

ties <- read_csv("data/dlt1-edgelist.csv", 
                 col_types = cols(Sender = col_character(), 
                                  Receiver = col_character(), 
                                  `Category Text` = col_skip(), 
                                  `Comment ID` = col_character(), 
                                  `Discussion ID` = col_character()))

ties

Note the addition of the col_types = argument for changing the column types to character strings since the numbers for for those particular columns indicate actors (Sender and Reciever) and attributes (Comment_ID and Discussion_Id). We also skipped the Category Text.

RStudio Tip: Importing data and dealing with data types can be a bit tricky, especially for beginners. Fortunately, RStudio has an “Import Dataset” feature in the Environment Pane that can help you use the {readr} package and associated functions to greatly facilitate this process.

Your Turn

Consider the example pictured below of a discussion thread from the Planning for the Digital Learning Transition in K-12 Schools (DLT 1) where our data orginated. This thread was initiated by participant I, so the comments by J and N are considered to be directed at I. The comment of B, however, is a direct response to the comment by N as signaled by the use of the quote-feature as well as the explicit mentioning of N’s name within B’s comment.

Now answer the following questions as they relate to the DLT 1 edge-list we just read into R.

  1. Which actors in this thread are the Sender and the Reciever? Which actor is both?

  2. How many dyads are in this thread? Which pairs of actors are dyads?

Sidebar: Unfortunately, these types of nuances in discussion forum data as illustrated by this simple example are rarely captured through automated approaches to constructing networks. Fortunately, the dataset you are working with was carefully reviewed to try and capture more accurately the intended recipients of each reply.

Node Attributes

The second file is we’ll be using to help understand out network and the actors involved contains all the nodes or actors (i.e., participants who posted to the discussion forum) as well as some of their attributes such as gender and years of experience in education.

Carolyn (2013) notes that most social network analyses include variables that describe attributes of actors, ones that are either categorical (e.g., sex, race, etc.) or continuous in nature (e.g., test scores, number of times absent, etc.). These attributes that can be incorporated into a network graph or model to making it much more informative and can aid in testing or generating hypotheses.

These attribute variables are typically included in a rectangular array, or dataframe, that mimics the actor-by-attribute that is the dominant convention in social science, i.e. rows represent cases, columns represent variables, and cells consist of values on those variables.

As and aside, Carolyn also refers to this historical preference by researchers for “actor-by-attribute” data, in the absence of relational data in which the actor has been removed their social context, as the “sociological meatgrinder” in action. Specifically, this historical approach assumes that the actor does not interact with anyone else in the study and that outcomes are solely dependent of the characteristics of the individual.

Regardless, let’s read in our node attribute file and take a look at the actors and their attributes included in our dataset:

actors <- read_csv("data/dlt1-nodes.csv", 
                   col_types = cols(UID = col_character(), 
                                    Facilitator = col_character(), 
                                    expert = col_character(), 
                                    connect = col_character()))

Your Turn

Use the code chunk below and a function of your choosing to take a look at the actors data frame:

Match up the attributes included in the node file with the following codebook descriptors. The first one has been done as an example.

  • Facilitator = Identification of course facilitator (1 = instructor)
  • Dummy variable for whether participants listed networking/collaboration with others as one of their course goals on the registration form
  • Identifier of “expert panelists” invited to course to share experience through recorded Q&A
  • Identification of course facilitator (1 = instructor)
  • Professional role (eg, teacher, librarian, administrator)
  • Years of experience as an educator
  • Works with elementary, middle, and/or high school students
  • Initial assignment of discussion group

2b. Create a Network Object

network <- graph_from_data_frame(d=ties, 
                             vertices=actors, 
                             directed=T) 

network
IGRAPH d47d41c DN-- 445 2529 -- 
+ attr: name (v/c), Facilitator (v/c), role1 (v/c), experience (v/n), experience2
| (v/c), grades (v/c), location (v/c), region (v/c), country (v/c), group (v/c),
| gender (v/c), expert (v/c), connect (v/c), Timestamp (e/c), Discussion Title
| (e/c), Discussion Category (e/c), Parent Category (e/c), Discussion Identifier
| (e/c), Comment ID (e/c), Discussion ID (e/c)
+ edges from d47d41c (vertex names):
 [1] 360->444 356->444 356->444 344->444 392->444 219->444 318->444 4  ->444 355->356 355->444
[11] 4  ->444 310->444 248->444 150->444 19 ->310 216->19  19 ->444 19 ->4   217->310 385->444
[21] 217->444 393->444 217->19  256->219 253->444 301->444 301->444 143->444 218->19  361->217
[31] 30 ->444 30 ->444 335->444 166->444 156->219 173->444 223->444 219->19  219->253 261->444
+ ... omitted several edges
LS0tCnRpdGxlOiAnVW5pdCAxIFdhbGt0aHJvdWdoOiBQZWVyIEludGVyYWN0aW9uICYgTU9PQy1FZHMnCmF1dGhvcjogIkRyLiBTaGF1biBLZWxsb2dnIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksJyVCICVlLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgdGhlbWU6IGRlZmF1bHQKICAgIHRvY19kZXB0aDogNApzdWJ0aXRsZTogRUNJIDU4OSBTb2NpYWwgTmV0d29yayBBbmFseXNpcyBhbmQgRWR1Y2F0aW9uCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogNzIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgMS4gUFJFUEFSRQoKRHVyaW5nIHRoZSBzZWNvbmQgd2VlayBvZiBlYWNoIHVuaXQsIHdlJ2xsICoqIndhbGsgdGhyb3VnaCIqKiBhIGJhc2ljCnJlc2VhcmNoIHdvcmtmbG93LCBvciBkYXRhIGFuYWx5c2lzIHByb2Nlc3MsIG1vZGVsZWQgYWZ0ZXIgdGhlCkRhdGEtSW50ZW5zaXZlIFJlc2VhcmNoIFdvcmtmbG93IGZyb20gW0xlYXJuaW5nIEFuYWx5dGljcyBHb2VzIHRvClNjaG9vbF0oaHR0cHM6Ly9jYXRhbG9nLmxpYi5uY3N1LmVkdS9jYXRhbG9nL05DU1U0ODYyMTM0KSAoS3J1bW0gZXQgYWwuLAoyMDE4KToKCiFbRmlndXJlIDIuMiBTdGVwcyBvZiBEYXRhLUludGVuc2l2ZSBSZXNlYXJjaApXb3JrZmxvd10oaW1nL3dvcmtmbG93LnBuZyl7d2lkdGg9IjgwJSJ9CgpFYWNoIHdhbGt0aHJvdWdoIHdpbGwgZm9jdXMgb24gYSBiYXNpYyBhbmFseXNpcyBndWlkZWQgYnkgdGhlIHNvY2lhbApuZXR3b3JrIHBlcnNwZWN0aXZlLgoKVGhpcyB3ZWVrLCBvdXIgZm9jdXMgd2lsbCBiZSBvbiBwcmVwYXJpbmcgcmVsYXRpb25hbCBkYXRhIGZvciBhbmFseXNpcywKbG9va2luZyBhdCBzb21lIGJhc2ljIG5ldHdvcmsgc3RhdHMsIGFuZCBjcmVhdGluZyBhIG5ldHdvcmsKdmlzdWFsaXphdGlvbiB0aGF0IGhlbHBzIGlsbHVzdHJhdGUga2V5IGZpbmRpbmdzLiBTcGVjaWZpY2FsbHksIHRoZSBVbml0CjEgV2Fsa3Rocm91Z2ggd2lsbCBjb3ZlciB0aGUgZm9sbG93aW5nIHdvcmtmbG93IHRvcGljczoKCjEuICAqKlByZXBhcmUqKjogUHJpb3IgdG8gYW5hbHlzaXMsIHdlJ2xsIHRha2UgYSBsb29rIGF0IHRoZSBjb250ZXh0IGluCiAgICB3aGljaCBhcmUgZGF0YSBpcyBkZXJpdmVkLCB5b3UncmUgd29ya2luZyB3aXRoIHNvIHlvdSBjYW4gZm9ybXVsYXRlCiAgICB1c2VmdWwgYW5kIGFuc3dlcmFibGUgcXVlc3Rpb25zLiBZb3UnbGwgYWxzbyBuZWVkIHRvIHNldCB1cCBhCiAgICAiUHJvamVjdCIgZm9yIG91ciBVbml0IDEgd2Fsa3Rocm91Z2guCgoyLiAgKipXcmFuZ2xlKio6IFdyYW5nbGluZyBkYXRhIGVudGFpbHMgdGhlIHdvcmsgb2YgbWFuaXB1bGF0aW5nLAogICAgY2xlYW5pbmcsIHRyYW5zZm9ybWluZywgYW5kIG1lcmdpbmcgZGF0YS4gSW4gc2VjdGlvbiAyIHdlIGZvY3VzIG9uCiAgICByZWFkaW5nLCByZWR1Y2luZywgYW5kIHRpZHlpbmcgb3VyIGRhdGEuCgozLiAgKipFeHBsb3JlKio6IEluIHNlY3Rpb24gMywgd2UgdXNlIHNpbXBsZSBzdW1tYXJ5IHN0YXRpc3RpY3MsIG1vcmUKICAgIHNvcGhpc3RpY2F0ZWQgYXBwcm9hY2hlcyBsaWtlIHRlcm0gZnJlcXVlbmN5LWludmVyc2UgZG9jdW1lbnQKICAgIGZyZXF1ZW5jeSAodGYtaWRmKSwgYW5kIGJhc2ljIGRhdGEgdmlzdWFsaXphdGlvbiB0byBleHBsb3JlIG91ciBkYXRhCiAgICBhbmQgc2VlIHdoYXQgaW5zaWdodCBpdCBwcm92aWRlcyBpbiByZXNwb25zZSB0byBvdXIgcXVlc3Rpb24uCgo0LiAgKipNb2RlbCoqOiBXaGlsZSB3ZSB3b24ndCBpbnZlc3RpZ2F0ZSBhcHByb2FjaGVzIHRvICoqTW9kZWwqKiBvdXIKICAgIGRhdGEgdW50aWwgVW5pdCAzIHdoZW4gd2UgbGVhcm4gYWJvdXQgY29tbXVuaXR5IGRldGVjdGlvbiBhbGdvcml0aG1zCiAgICBhbmQgZXhwb25lbnRpYWwgcmFuZG9tIGdyYXBoIG1vZGVscyAoRVJHTSksIHdlIHdpbGwgc2VlIGhvdyBtb2RlbGluZwogICAgaGFzIGJlZW4gYXBwbGllZC4KCjUuICAqKkNvbW11bmljYXRlKio6CgojIyAxYS4gUmV2aWV3IHRoZSBSZXNlYXJjaAoKUHJpb3IgdG8gYW5hbHlzaXMsIGl0J3MgY3JpdGljYWwgdG8gdW5kZXJzdGFuZCB0aGUgY29udGV4dCBhbmQgZGF0YQpzb3VyY2VzIGF2YWlsYWJsZSBzbyB5b3UgY2FuIGZvcm11bGF0ZSB1c2VmdWwgcXVlc3Rpb25zIHRoYXQgY2FuIGJlCmZlYXNpYmx5IGFkZHJlc3NlZCBieSB5b3VyIGRhdGEuIEZvciB0aGlzIHNlY3Rpb24sIHdlJ2xsIGZvY3VzIG9uIHRoZQpmb2xsb3dpbmcgdG9waWNzOgoKSW4gW1NvY2lhbCBOZXR3b3JrIEFuYWx5c2lzIGFuZCBFZHVjYXRpb246IFRoZW9yeSwgTWV0aG9kcyAmCkFwcGxpY2F0aW9uc10oaHR0cHM6Ly9tZXRob2RzLnNhZ2VwdWIuY29tL2Jvb2svc29jaWFsLW5ldHdvcmstYW5hbHlzaXMtYW5kLWVkdWNhdGlvbiksCkNhcm9seW4gKDIwMTMpIG5vdGVzIHRoYXQ6Cgo+IHRoZSAqKnNvY2lhbCBuZXR3b3JrIHBlcnNwZWN0aXZlKiogaXMgb25lIGNvbmNlcm5lZCB3aXRoIHRoZSBzdHJ1Y3R1cmUKPiBvZiByZWxhdGlvbnMgYW5kIHRoZSBpbXBsaWNhdGlvbiB0aGlzIHN0cnVjdHVyZSBoYXMgb24gaW5kaXZpZHVhbCBvcgo+IGdyb3VwIGJlaGF2aW9yIGFuZCBhdHRpdHVkZXMKCk1vcmUgc3BlY2lmaWNhbGx5LCBDYXJvbHluIGNpdGVzIHRoZSBmb2xsb3dpbmcgZm91ciBmZWF0dXJlcyB1c2VkIGJ5CkZyZWVtYW4gKDIwMDQpIHRvIGRlZmluZSB0aGUgc29jaWFsIG5ldHdvcmsgcGVyc3BlY3RpdmU6CgoxLiAgU29jaWFsIG5ldHdvcmsgYW5hbHlzaXMgaXMgKiptb3RpdmF0ZWQgYnkgYSByZWxhdGlvbmFsIGludHVpdGlvbioqCiAgICBiYXNlZCBvbiB0aWVzIGNvbm5lY3Rpbmcgc29jaWFsIGFjdG9ycy4KCjIuICBJdCBpcyBmaXJtbHkgKipncm91bmRlZCBpbiBzeXN0ZW1hdGljIGVtcGlyaWNhbCBkYXRhKiouCgozLiAgSXQgKiptYWtlcyoqICoqdXNlIG9mIGdyYXBoaWMgaW1hZ2VyeSoqIHRvIHJlcHJlc2VudCBhY3RvcnMgYW5kCiAgICB0aGVpciByZWxhdGlvbnMgd2l0aCBvbmUgYW5vdGhlci4KCjQuICBJdCAqKnJlbGllcyoqICoqb24qKiAqKm1hdGhlbWF0aWNhbCBhbmQvb3IgY29tcHV0YXRpb25hbCBtb2RlbHMqKiB0bwogICAgc3VjY2luY3RseSByZXByZXNlbnQgdGhlIGNvbXBsZXhpdHkgb2Ygc29jaWFsIGxpZmUuCgpGb3IgVW5pdCAxLCBvdXIgd2Fsa3Rocm91Z2ggd2lsbCBiZSBndWlkZWQgYnkgcHJldmlvdXMgcmVzZWFyY2ggYW5kCmV2YWx1YXRpb24gd29yayBjb25kdWN0ZWQgYnkgdGhlIEZyaWRheSBJbnN0aXR1dGUgZm9yIEVkdWNhdGlvbmFsCklubm92YXRpb24gYXMgcGFydCBvZiB0aGUgTWFzc2l2ZWx5IE9wZW4gT25saW5lIENvdXJzZXMgZm9yIEVkdWNhdG9ycwooTU9PQy1FZCkgaW5pdGlhdGl2ZS4KCiMjIyBBIFNvY2lhbCBOZXR3b3JrIFBlcnNwZWN0aXZlIGluIE1PT0MtRWRzCgohW10oaW1nL2lycm9kbC1hcnRpY2xlLnBuZyl7d2lkdGg9IjQwJSJ9CgpLZWxsb2dnLCBTLiwgQm9vdGgsIFMuLCAmIE9saXZlciwgSy4gKDIwMTQpLiBbQSBzb2NpYWwgbmV0d29yawpwZXJzcGVjdGl2ZSBvbiBwZWVyIHN1cHBvcnRlZCBsZWFybmluZyBpbiBNT09DcyBmb3IKZWR1Y2F0b3JzXShodHRwczovL2dpdGh1Yi5jb20vc2JrZWxsb2dnL2VjaS01ODkvYmxvYi9tYWluL3VuaXQtMS9saXQvc25hX21vb2NfaXJyb2RsX2JqZXRfYXJ0aWNsZXMucGRmKS7CoCpJbnRlcm5hdGlvbmFsClJldmlldyBvZiBSZXNlYXJjaCBpbiBPcGVuIGFuZCBEaXN0cmlidXRlZCBMZWFybmluZyoswqAqMTUqKDUpLCAyNjMtMjg5LgoKIyMjIyBSZXNlYXJjaCBDb250ZXh0CgpJbiB0aGUgc3ByaW5nIG9mIDIwMTMsIFRoZSBGcmlkYXkgSW5zdGl0dXRlIGxhdW5jaGVkIHRoZSBNT09DLUVkCkluaXRpYXRpdmUgdG8gZXhwbG9yZSB0aGUgcG90ZW50aWFsIG9mIGRlbGl2ZXJpbmcgcGVyc29uYWxpemVkLApoaWdoLXF1YWxpdHkgcHJvZmVzc2lvbmFsIGRldmVsb3BtZW50IHRvIGVkdWNhdG9ycyBhdCBzY2FsZSAoS2xlaW1hbiBldAphbC4sIDIwMTMpLiBJbiBjb2xsYWJvcmF0aW9uIHdpdGggdGhlIEFsbGlhbmNlIGZvciBFeGNlbGxlbnQgRWR1Y2F0aW9uLAp0aGUgRnJpZGF5IEluc3RpdHV0ZSBsYXVuY2hlZCB0aGlzIGluaXRpYXRpdmUgd2l0aCBhIDYtd2VlayBwaWxvdCBjb3Vyc2UKY2FsbGVkIFBsYW5uaW5nIGZvciB0aGUgRGlnaXRhbCBMZWFybmluZyBUcmFuc2l0aW9uIGluIEstMTIgU2Nob29scyAoRExUCjEpLCB3aGljaCB3YXMgb2ZmZXJlZCBhZ2FpbiBpbiBTZXB0ZW1iZXIgMjAxMyAoRExUIDIpLiBUaGlzIGNvdXJzZSB3YXMKZGVzaWduZWQgdG8gaGVscCBzY2hvb2wgYW5kIGRpc3RyaWN0IGxlYWRlcnMgcGxhbiBhbmQgaW1wbGVtZW50IEstMTIKZGlnaXRhbCBsZWFybmluZyBpbml0aWF0aXZlcy4KCkFjYWRlbWljcywgYXMgd2VsbCBhcyBwdW5kaXRzIGZyb20gdHJhZGl0aW9uYWwgYW5kIG5ldyBtZWRpYSwgaGF2ZQpyYWlzZWQgYSBudW1iZXIgb2YgY29uY2VybnMgYWJvdXQgTU9PQ3MsIGluY2x1ZGluZyB0aGUgbGFjayBvZgppbnN0cnVjdGlvbmFsIGFuZCBzb2NpYWwgc3VwcG9ydHMuIEFtb25nIHRoZSBjb3JlIGRlc2lnbiBwcmluY2lwbGVzIG9mCk1PT0MtRWRzIGFyZSBjb2xsYWJvcmF0aW9uIGFuZCBwZWVyLXN1cHBvcnRlZCBsZWFybmluZy4gSXQgaXMgYW4KYXNzdW1wdGlvbiBvZiB0aGlzIHN0dWR5IHRoYXQgY2hhbGxlbmdlcyBhcmlzaW5nIGZvcm0gdGhpcyBwcm9ibGVtIG9mCnNjYWxlIGNhbiBiZSBhZGRyZXNzZWQgYnkgbGV2ZXJhZ2luZyB0aGVzZSBtYXNzaXZlIG51bWJlcnMgdG8gZGV2ZWxvcApyb2J1c3Qgb25saW5lIGxlYXJuaW5nIGNvbW11bml0aWVzLgoKVGhpcyBtaXhlZC1tZXRob2RzIGNhc2Ugc3R1ZHkgdXNlZCBib3RoIFNOQSBhbmQgcXVhbGl0YXRpdmUgbWV0aG9kcyB0bwpiZXR0ZXIgdW5kZXJzdGFuZCBwZWVyIHN1cHBvcnQgaW4gTU9PQy1FZHMgdGhyb3VnaCBhbiBleGFtaW5hdGlvbiBvZiB0aGUKY2hhcmFjdGVyaXN0aWNzLCBtZWNoYW5pc21zLCBhbmQgb3V0Y29tZXMgb2YgcGVlciBuZXR3b3Jrcy4gRmluZGluZ3MKZnJvbSB0aGlzIHN0dWR5IGRlbW9uc3RyYXRlIHRoYXQgZXZlbiB3aXRoIHRlY2hub2xvZ3kgYXMgYmFzaWMgYXMgYQpkaXNjdXNzaW9uIGZvcnVtLCBNT09DcyBjYW4gYmUgbGV2ZXJhZ2VkIHRvIGZvc3RlciB0aGVzZSBuZXR3b3JrcyBhbmQKZmFjaWxpdGF0ZSBwZWVyLXN1cHBvcnRlZCBsZWFybmluZy4gQWx0aG91Z2ggdGhpcyBzdHVkeSB3YXMgbGltaXRlZCB0bwp0d28gdW5pcXVlIGNhc2VzIGFsb25nIHRoZSB3aWRlIHNwZWN0cnVtIG9mIE1PT0NzLCB0aGUgbWV0aG9kcyBhcHBsaWVkCnByb3ZpZGUgb3RoZXIgcmVzZWFyY2hlcnMgd2l0aCBhbiBhcHByb2FjaCBmb3IgYmV0dGVyIHVuZGVyc3RhbmRpbmcgdGhlCmR5bmFtaWMgcHJvY2VzcyBvZiBwZWVyIHN1cHBvcnRlZCBsZWFybmluZyBpbiBNT09Dcy4KCiMjIyMgRGF0YSBTb3VyY2VzCgoqKk1PT0MtRWQgcmVnaXN0cmF0aW9uIGZvcm0uKiogQWxsIHBhcnRpY2lwYW50cyBjb21wbGV0ZWQgYSByZWdpc3RyYXRpb24KZm9ybSBmb3IgZWFjaCBNT09DLUVkIGNvdXJzZS4gVGhlIHJlZ2lzdHJhdGlvbiBmb3JtIGNvbnNpc3RzIG9mCnNlbGYtcmVwb3J0ZWQgZGVtb2dyYXBoaWMgZGF0YSwgaW5jbHVkaW5nIGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gdGhlaXIKcHJvZmVzc2lvbmFsIHJvbGUgYW5kIHdvcmsgc2V0dGluZywgeWVhcnMgb2YgZXhwZXJpZW5jZSBpbiBlZHVjYXRpb24sCmFuZCBwZXJzb25hbCBsZWFybmluZyBnb2Fscy4KCioqTU9PQy1FZCBkaXNjdXNzaW9uIGZvcnVtcy4qKiBBbGwgcGVlciBpbnRlcmFjdGlvbiwgaW5jbHVkaW5nIHBlZXIKZGlzY3Vzc2lvbiwgZmVlZGJhY2ssIGFuZCByZWFjdGlvbnMgKGUuZy4sIGxpa2VzKSwgdGFrZSBwbGFjZSB3aXRoaW4gdGhlCmZvcnVtIGFyZWEgb2YgTU9PQy1FZHMsIHdoaWNoIGFyZSBwb3dlcmVkIGJ5IFZhbmlsbGEgRm9ydW1zLiBCZWNhdXNlIG9mCnRoZSBzcGVjaWZpYyBmb2N1cyBvbiBwZWVyIHN1cHBvcnRlZCBsZWFybmluZywgcG9zdGluZ3MgdG8gb3IgZnJvbQpjb3Vyc2UgZmFjaWxpdGF0b3JzIGFuZCBzdGFmZiB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgZGF0YSBzZXQuIEZpbmFsbHksCmFuYWx5c2VzIGRlc2NyaWJlZCBiZWxvdyBleGNsdWRlIG1vcmUgcGFzc2l2ZSBmb3JtcyBvZiBpbnRlcmFjdGlvbnMKKGkuZS4sIHJlYWQgYW5kIHJlYWN0aW9uIGxvZ3MpLCBhbmQgaW5jbHVkZSBvbmx5IHBvc3RpbmdzIGFtb25nIHBlZXJzLgoKRm9yIG91ciBVbml0IDEgd2Fsa3Rocm91Z2gsIHdlJ2xsIHRha2UgYSBsb29rIGF0IGRhdGEgZnJvbSB0aGUgb3JpZ2luYWwKRGlnaXRhbCBMZWFybmluZyBUcmFuc2l0aW9uIGluIEstMTIgU2Nob29scyAoRExUIDEpIHdoaWNoIHdhcyBub3QKaW5jbHVkZWQgaW4gdGhpcyBzdHVkeSBzbyB3ZSBjYW4gbWFrZSBjb21wYXJpc29ucyBpbiBvdXIgYW5hbHlzaXMgdG8gdGhlCkRMVCAyIGNvdXJzZSByZXBvcnRlZCBpbiB0aGlzIHN0dWR5LiBBbHNvLCBmb3IgeW91ciBpbmRlcGVuZGVudAphbmFseXNpcywgeW91IG1heSB3YW50IHRvIGNvbnNpZGVyIHdvcmtpbmcgd2l0aCB0aGUgRExUIDIgZGF0YSB0byBzZWUgaWYKeW91IGNhbiByZXBsaWNhdGUgc29tZSBvZiB0aGUgZmluZGluZ3MgZnJvbSB0aGlzIHBhcGVyIQoKIyMjIyBbKipZb3VyIFR1cm4qKl17c3R5bGU9ImNvbG9yOiBncmVlbjsifSAqKuKktSoqCgpUYWtlIGEgcXVpY2sgbG9vayBhdCB0aGUgKkRlc2NyaXB0aW9uIG9mIHRoZSBEYXRhc2V0KiBzZWN0aW9uIGZyb20gdGhlCltNYXNzaXZlbHkgT3BlbiBPbmxpbmUgQ291cnNlIGZvciBFZHVjYXRvcnMgKE1PT0MtRWQpIG5ldHdvcmsKZGF0YXNldF0oaHR0cHM6Ly9naXRodWIuY29tL3Nia2VsbG9nZy9lY2ktNTg5L2Jsb2IvbWFpbi91bml0LTEvbGl0L2JqZXRfMTIzMTJfUmV2LnBkZikKQkpFVCBhcnRpY2xlLCBhcyB3ZWxsIGFzIHRoZSBhY2NvbXBhbnlpbmcgZGF0YSBzZXRzIHRoYXQgd2UnbGwgYmUgdXNpbmcKZm9yIHRoaXMgd2Fsa3Rocm91Z2ggc3RvcmVkIG9uIFtIYXJ2YXJkCkRhdGF2ZXJzZV0oaHR0cHM6Ly9kYXRhdmVyc2UuaGFydmFyZC5lZHUvZGF0YXNldC54aHRtbD9wZXJzaXN0ZW50SWQ9ZG9pOjEwLjc5MTAvRFZOL1paSDNVQikuCgpJbiB0aGUgc3BhY2UgYmVsb3csIHR5cGUgYSBicmllZiByZXNwb25zZSB0byB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uczoKCjEuICBXaGF0IHdlcmUgc29tZSBvZiB0aGUgc3RlcHMgbmVjZXNzYXJ5IHRvIGNvbnN0cnVjdCB0aGlzIGRhdGFzZXQ/CgogICAgLSAgIAoKMi4gIE5hbWUgdHdvICJub2RlIGF0dHJpYnV0ZXMiIGZyb20gdGhlIGRhdGFzZXQgdGhhdCBtaWdodCBiZSB1c2VmdWwgZm9yCiAgICBwcmVkaWN0aW5nIHBhcnRpY2lwYW50cyB3aG8gbWF5IGJlIG1vcmUgZW5nYWdlZCBvciBjZW50cmFsIHRvIHRoZQogICAgbmV0d29yaz8gV2h5IGRpZCB5b3Ugc2VsZWN0IHRob3NlIHR3bz8KCiAgICAtICAgCgozLiAgV2hhdCBlbHNlIGRvIHlvdSBub3RpY2Uvd29uZGVyIGFib3V0IHRoaXMgZGF0YXNldD8KCiAgICAtICAgCgojIyAxYi4gSWRlbnRpZnkgUmVzZWFyY2ggUXVlc3Rpb25zCgpBIFNvY2lhbCBOZXR3b3JrIFBlcnNwZWN0aXZlIG9uIFBlZXIgU3VwcG9ydGVkIExlYXJuaW5nIGluIE1PT0MtRWRzIHdhcwpmcmFtZWQgYnkgdGhyZWUgcHJpbWFyeSByZXNlYXJjaCBxdWVzdGlvbnMgcmVsYXRlZCB0byBwZWVyIHN1cHBvcnRlZApsZWFybmluZzoKCjEuICBXaGF0IGFyZSB0aGUgcGF0dGVybnMgb2YgcGVlciBpbnRlcmFjdGlvbiBhbmQgdGhlIHN0cnVjdHVyZSBvZiBwZWVyCiAgICBuZXR3b3JrcyB0aGF0IGVtZXJnZSBvdmVyIHRoZSBjb3Vyc2Ugb2YgYSBNT09DLUVkPwoKMi4gIFRvIHdoYXQgZXh0ZW50IGRvIHBhcnRpY2lwYW50IGFuZCBuZXR3b3JrIGF0dHJpYnV0ZXMgKGUuZy4sCiAgICBob21vcGhpbHksIHJlY2lwcm9jaXR5LCB0cmFuc2l0aXZpdHkpIGFjY291bnQgZm9yIHRoZSBzdHJ1Y3R1cmUgb2YKICAgIHRoZXNlIG5ldHdvcmtzPwoKMy4gIFRvIHdoYXQgZXh0ZW50IGRvIHRoZXNlIG5ldHdvcmtzIHJlc3VsdCBpbiB0aGUgY28tY29uc3RydWN0aW9uIG9mCiAgICBuZXcga25vd2xlZGdlPwoKRm9yIG91ciB2ZXJ5IGZpcnN0IHdhbGt0aHJvdWdoLCB3ZSBhcmUgZ29pbmcgdG8gZm9jdXMgZXhjbHVzaXZlbHkgb24gUlExCmZyb20gdGhlIG9yaWdpbmFsIHN0dWR5LiBPdXIgcXVlc3Rpb24gb2YgaW50ZXJlc3QgaXMgZm9jdXNlZCBvbiB2ZXJ5CmJhc2ljIHF1ZXN0aW9ucyBhYm91dCBvdXIgZWR1Y2F0b3IgbmV0d29yazoKCj4gSG93LCBhbmQgdG8gd2hhdCBleHRlbnQsIGRpZCBlZHVjYXRvcnMgZW5nYWdlIHdpdGggb3RoZXIgcGFydGljaXBhbnRzCj4gaW4gdGhlIGRpc2N1c3Npb24gZm9ydW1zPwoKIyMjIFsqKllvdXIgVHVybioqXXtzdHlsZT0iY29sb3I6IGdyZWVuOyJ9ICoq4qS1KioKCkJhc2VkIG9uIG91ciBjb3Vyc2UgcmVhZGluZ3MgYW5kIHlvdXIgc2VsZi1zZWxlY3RlZCByZWFkaW5ncywgd2hhdApzdWJxdWVzdGlvbnMsIG9yIG1vcmUgc3BlY2lmaWMgcmVzZWFyY2ggcXVlc3Rpb25zLCBtaWdodCBhc2sgdGhhdCBoZWxwCnlvdSBhbnN3ZXIgdGhlIGJyb2FkZXIgcXVlc3Rpb24gd2UnbGwgYmUgZm9jdXNlZCBvbiBmb3IgdGhpcwp3YWxrdGhyb3VnaD8KCkluIHRoZSBzcGFjZSBiZWxvdywgdHlwZSBhIGJyaWVmIHJlc3BvbnNlIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOgoKXC0KCiMjIDFjLiBDaGVjayBQYWNrYWdlcwoKQXMgaGlnaGxpZ2h0ZWQgaW4gW0NoYXB0ZXIgNiBvZiBEYXRhIFNjaWVuY2UgaW4gRWR1Y2F0aW9uIFVzaW5nClJdKGh0dHBzOi8vZGF0YXNjaWVuY2VpbmVkdWNhdGlvbi5jb20vYzA2Lmh0bWwjYzA2cCkgKERTSUVVUik6Cgo+IFBhY2thZ2VzIGFyZSBzaGFyZWFibGUgY29sbGVjdGlvbnMgb2YgUiBjb2RlIHRoYXQgY2FuIGNvbnRhaW4KPiBmdW5jdGlvbnMsIGRhdGEsIGFuZC9vciBkb2N1bWVudGF0aW9uLiBQYWNrYWdlcyBpbmNyZWFzZSB0aGUKPiBmdW5jdGlvbmFsaXR5IG9mIFIgYnkgcHJvdmlkaW5nIGFjY2VzcyB0byBhZGRpdGlvbmFsIGZ1bmN0aW9ucyB0byBzdWl0Cj4gYSB2YXJpZXR5IG9mIG5lZWRzLgoKTGV0J3MgY2hlY2sgdG8gc2VlIHdoaWNoIHBhY2thZ2VzIGhhdmUgYWxyZWFkeSBiZWVuIGxvYWRlZCBpbnRvIG91cgpSU3R1ZGlvIENsb3VkIHdvcmtzcGFjZS4gVGFrZSBhIGxvb2sgYXQgdGhlIHRoZSBGaWxlcywgUGxvdHMsICYgUGFja2FnZXMKUGFuZSBpbiB0aGUgbG93ZXIgcmlnaHQgaGFuZCBjb3JuZXIgb2YgUlN0dWRpbyBDbG91ZCB0byBtYWtlIHN1cmUgdGhlc2UKcGFja2FnZXMgaGF2ZSBiZWVuIGluc3RhbGxlZCBhbmQgbG9hZGVkOgoKIVtdKGltZy9wYWNrYWdlcy1wYW5lLnBuZyl7d2lkdGg9IjkwJSJ9CgpZb3Ugc2hvdWxkIHNlZSBzb21lIGZhbWlsaWFyIHRpZHl0ZXh0IHBhY2thZ2VzIGZyb20gb3VyIFtHZXR0aW5nIFN0YXJ0ZWQKV2Fsa3Rocm91Z2hdKGh0dHBzOi8vc2JrZWxsb2dnLmdpdGh1Yi5pby9lY2ktNTg5L3VuaXQtMC91bml0LTAtd2Fsa3Rocm91Z2guaHRtbCkKbGlrZSB7ZHBseXJ9IGFuZCB7cmVhZHJ9IHdoaWNoIHdlJ2xsIGJlIHVzaW5nIGFnYWluIHNob3J0bHkuIFlvdSBzaG91bGQKYWxzbyBzZWUgYW4gaW1wb3J0YW50IHBhY2thZ2UgY2FsbCB7aWdyYXBofSB0aGF0IHdpbGwgcmVseSBvbiBoZWF2aWx5CmZvciBvdXIgbmV0d29yayBhbmFseXNlcy4KCklmIHlvdSBhcmUgd29ya2luZyBpbiBSU3R1ZGlvIERlc2t0b3AsIG9yIG5vdGljZSB0aGF0IHRoZSBwYWNrYWdlcyBoYXZlCm5vdCBiZWVuIGluc3RhbGxlZCBhbmQvb3IgbG9hZGVkLCBydW4gdGhlIGZvbGxvd2luZyBgaW5zdGFsbC5wYWNrYWdlcygpYApmdW5jdGlvbiBjb2RlIHRvIGluc3RhbGwgdGhlIHt0aWR5dmVyc2V9IGFuZCB7aWdyYXBofSBwYWNrYWdlczoKCmBgYHtyLCBldmFsPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQppbnN0YWxsLnBhY2thZ2VzKCJpZ3JhcGgiKSAKYGBgCgpBbmQgYGxpYnJhcnkoKWAgZnVuY3Rpb24gdG8gbG9hZCB0aGVtOgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGlncmFwaCkKYGBgCgojIyMgaWdyYXBoICoq8J+TpioqCgohW10oaW1nL2lncmFwaC5wbmcpe3dpZHRoPSIzMCUifQoKQXQgdGhlIGVuZCBvZiB0aGlzIHdlZWssIEknbGwgYXNrIHRoYXQgeW91IHNoYXJlIHdpdGggbWUgeW91ciByIHNjcmlwdAphcyBldmlkZW5jZSB0aGF0IHlvdSBoYXZlIGNvbXBsZXRlZCB0aGUgd2Fsa3Rocm91Z2guIEFsdGhvdWdoIEkgaGlnaGx5CnJlY29tbWVuZCB0aGF0IHRoYXQgeW91IG1hbnVhbGx5IHR5cGUgdGhlIGNvZGUgc2hhcmVkIHRocm91Z2hvdXQgdGhpcwp3YWxrdGhyb3VnaCwgZm9yIGxhcmdlIGJsb2NrcyBvZiB0ZXh0IGl0IG1heSBiZSBlYXNpZXIgdG8gY3V0IGFuZCBwYXN0ZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyAyLiBXUkFOR0xFCgpJbiBnZW5lcmFsLCBkYXRhIHdyYW5nbGluZyBpbnZvbHZlcyBzb21lIGNvbWJpbmF0aW9uIG9mIGNsZWFuaW5nLApyZXNoYXBpbmcsIHRyYW5zZm9ybWluZywgYW5kIG1lcmdpbmcgZGF0YSAoV2lja2hhbSAmIEdyb2xlbXVuZCwgMjAxNykuClRoZSBpbXBvcnRhbmNlIG9mIGRhdGEgd3JhbmdsaW5nIGlzIGRpZmZpY3VsdCB0byBvdmVyc3RhdGUsIGFzIGl0Cmludm9sdmVzIHRoZSBpbml0aWFsIHN0ZXBzIG9mIGdvaW5nIGZyb20gdGhlIHJhdyBkYXRhIHRvIGEgZGF0YXNldCB0aGF0CmNhbiBiZSBleHBsb3JlZCBhbmQgbW9kZWxlZCAoS3J1bW0gZXQgYWwsIDIwMTgpLgoKRm9yIG91ciBkYXRhIHdyYW5nbGluZyB0aGlzIHdlZWssIHdlJ3JlIGtlZXBpbmcgaXQgc2ltcGxlIHNpbmNlIHdvcmtpbmcKd2l0aCBuZXR3b3JrIGRhdGEgaXMgYSBiaXQgb2YgYSBkZXBhcnR1cmUgZnJvbSBvdXIgd29ya2luZyB3aXRoCnJlY3Rhbmd1bGFyIGRhdGEgZnJhbWVzLiBPdXIgcHJpbWFyeSBnb2FscyBmb3IgVW5pdCAxIGFyZSBsZWFybmluZyBob3cKdG86CgphLiAgKipJbXBvcnQgRGF0YSoqLiBCZWZvcmUgd29ya2luZyB3aXRoIGRhdGEsIHdlIG5lZWQgdG8gInJlYWQiIGl0IGludG8KICAgIFIgYW5kIG9uY2UgaW1wb3J0ZWQsIHdlJ2xsIHRha2UgYXQgZGlmZmVyZW50IHdheXMgdG8gdmlldyBvdXIgZGF0YQogICAgaW4gUi4KCmIuICAqKkNyZWF0ZSBhIE5ldHdvcmsgT2JqZWN0KiouCgpjLiAgKipTaW1wbGlmeSBOZXR3b3JrKiouIEZpbmFsbHksIHdlJ2xsIGxlYXJuIGFib3V0IGEgaGFuZHkKICAgIGBzaW1wbGlmeSgpYCBmdW5jdGlvbiBpbiB0aGUge2lncmFwaH0gcGFja2FnZSBmb3IgcmVtb3ZpbmcgdGllcyB0aGF0CiAgICAuCgojIyAyYS4gSW1wb3J0IERhdGEKCiMjIyBUaGUgRWRnZS1MaXN0IEZvcm1hdAoKVG8gZ2V0IHN0YXJ0ZWQsIHdlIG5lZWQgdG8gaW1wb3J0LCBvciAicmVhZCIsIG91ciBkYXRhIGludG8gUi4gVGhlCmZ1bmN0aW9uIHVzZWQgdG8gaW1wb3J0IHlvdXIgZGF0YSB3aWxsIGRlcGVuZCBvbiB0aGUgZmlsZSBmb3JtYXQgb2YgdGhlCmRhdGEgeW91IGFyZSB0cnlpbmcgdG8gaW1wb3J0LCBidXQgUiBpcyBwcmV0dHkgYWRlcHQgYXQgd29ya2luZyB3aXRoCm1hbnkgZmlsZXMgdHlwZXMuCgpUYWtlIGEgbG9vayBpbiB0aGUgYGRhdGFgIGZvbGRlciBpbiB5b3VyIEZpbGVzIHBhbmUuIFlvdSBzaG91bGQgc2VlIHRoZQpmb2xsb3dpbmcgLmNzdiBmaWxlczoKCi0gICBgZGx0MS1lZGdlbGlzdC5jc3ZgCgotICAgYGRsdDEtbm9kZXMuY3N2YAoKQXMgaXRzIG5hbWUgaW1wbGllcywgdGhlIGZpcnN0IGZpbGUgYGRsdDEtZWRnZWxpc3QuY3N2YCBpcyBhbiBlZGdlLWxpc3QKdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIHRpZSwgb3IgcmVsYXRpb24gYmV0d2VlbiB0d28gYWN0b3JzCmluIGEgbmV0d29yay4gSW4gdGhpcyBjb250ZXh0LCBhICJ0aWUiIGlzIGEgcmVwbHkgYnkgb25lIHBhcnRpY2lwYW50IGluCnRoZSBkaXNjdXNzaW9uIGZvcnVtIHRvIHRoZSBwb3N0IG9mIGFub3RoZXIgcGFydGljaXBhbnQgLSBvciBpbiBzb21lCmNhc2VzIHRvIHRoZWlyIG93biBwb3N0ISBUaGVzZSB0aWVzIGJldHdlZW4gYSBzaW5nbGUgYWN0b3IgYXJlIGNhbGxlZAoic2VsZi1sb29wcyIgYW5kIGFzIHdlJ2xsIHNlZSBsYXRlciBpbiB0aGlzIHNlY3Rpb24sIGlncmFwaCBoYXMgYQpzcGVjaWFsIGZ1bmN0aW9uIHRvIHJlbW92ZSB0aGVzZSBzZWxmIGxvb3BzIGZyb20gYSBzb2Npb2dyYW0sIG9yIG5ldHdvcmsKdmlzdWFsaXphdGlvbi4KClRoZSBlZGdlLWxpc3QgZm9ybWF0IGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIG90aGVyIGZvcm1hdHMgeW91IGhhdmUKbGlrZWx5IHdvcmtlZCB3aXRoIGJlZm9yZSBpbiB0aGF0IHRoZSB2YWx1ZXMgaW4gdGhlIGZpcnN0IHR3byBjb2x1bW5zCmVhY2ggcm93IHJlcHJlc2VudCBhIGR5YWQsIG9yIHRpZSBiZXR3ZWVuIHR3byBub2RlcyBpbiBhIG5ldHdvcmsuIEFuCmVkZ2UtbGlzdCBjYW4gYWxzbyBjb250YWluIG90aGVyIGluZm9ybWF0aW9uIHJlZ2FyZGluZyB0aGUgc3RyZW5ndGggb3IKZHVyYXRpb24gb2YgdGhlIHJlbGF0aW9uc2hpcCwgc29tZXRpbWUgY2FsbGVkICJ3ZWlnaHQiLCBpbiBhZGRpdGlvbiB0bwpvdGhlciAiZWRnZSBhdHRyaWJ1dGVzLiIKCkluIGFkZGl0aW9uIHRvCgotICAgYFNlbmRlcmAgPSBVbmlxdWUgaWRlbnRpZmllciBvZiBhdXRob3Igb2YgY29tbWVudAoKLSAgIGBSZWNlaXZlcmAgPSBVbmlxdWUgaWRlbnRpZmllciBvZiBpZGVudGlmaWVkIHJlY2lwaWVudCBvZiBjb21tZW50CgotICAgYFRpbWVzdGFtcGAgPSBUaW1lIGNvbW1lbnQgd2FzIHBvc3RlZAoKLSAgIGBQYXJlbnRgID0gUHJpbWFyeSBjYXRlZ29yeSBvciB0b3BpYyBvZiB0aHJlYWQKCi0gICBgQ2F0ZWdvcnlgID0gU3ViY2F0ZWdvcnkgb3Igc3VidG9waWMgb2YgdGhyZWFkCgotICAgYFRocmVhZF9pZGAgPSBVbmlxdWUgaWRlbnRpZmllciBvZiBhIHRocmVhZAoKLSAgIGBDb21tZW50X2lkYCA9IFVuaXF1ZSBpZGVudGlmaWVyIG9mIGEgY29tbWVudFxcCgpMZXQncyB1c2UgdGhlIGByZWFkX2NzdigpYCBmdW5jdGlvbiBmcm9tIHRoZSB7cmVhZHJ9IHBhY2thZ2UgaW50cm9kdWNlZAppbiB0aGUgR2V0dGluZyBTdGFydGVkIHdhbGt0aHJvdWdoIHRvIHJlYWQgaW4gb3VyIGVkZ2UtbGlzdCBhbmQgcHJpbnQKdGhlIG5ldyBgdGllc2AgZGF0YSBmcmFtZToKCmBgYHtyfQp0aWVzIDwtIHJlYWRfY3N2KCJkYXRhL2RsdDEtZWRnZWxpc3QuY3N2IiwgCiAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhTZW5kZXIgPSBjb2xfY2hhcmFjdGVyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVjZWl2ZXIgPSBjb2xfY2hhcmFjdGVyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYENhdGVnb3J5IFRleHRgID0gY29sX3NraXAoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29tbWVudCBJRGAgPSBjb2xfY2hhcmFjdGVyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYERpc2N1c3Npb24gSURgID0gY29sX2NoYXJhY3RlcigpKSkKCnRpZXMKYGBgCgpOb3RlIHRoZSBhZGRpdGlvbiBvZiB0aGUgYGNvbF90eXBlcyA9YCBhcmd1bWVudCBmb3IgY2hhbmdpbmcgdGhlIGNvbHVtbgp0eXBlcyB0byBjaGFyYWN0ZXIgc3RyaW5ncyBzaW5jZSB0aGUgbnVtYmVycyBmb3IgZm9yIHRob3NlIHBhcnRpY3VsYXIKY29sdW1ucyBpbmRpY2F0ZSBhY3RvcnMgKGBTZW5kZXJgIGFuZCBgUmVjaWV2ZXJgKSBhbmQgYXR0cmlidXRlcwooYENvbW1lbnRfSURgIGFuZCBgRGlzY3Vzc2lvbl9JZGApLiBXZSBhbHNvIHNraXBwZWQgdGhlIGBDYXRlZ29yeSBUZXh0YC4KCioqUlN0dWRpbyBUaXA6KiogSW1wb3J0aW5nIGRhdGEgYW5kIGRlYWxpbmcgd2l0aCBkYXRhIHR5cGVzIGNhbiBiZSBhIGJpdAp0cmlja3ksIGVzcGVjaWFsbHkgZm9yIGJlZ2lubmVycy4gRm9ydHVuYXRlbHksIFJTdHVkaW8gaGFzIGFuICJJbXBvcnQKRGF0YXNldCIgZmVhdHVyZSBpbiB0aGUgRW52aXJvbm1lbnQgUGFuZSB0aGF0IGNhbiBoZWxwIHlvdSB1c2UgdGhlCntyZWFkcn0gcGFja2FnZSBhbmQgYXNzb2NpYXRlZCBmdW5jdGlvbnMgdG8gZ3JlYXRseSBmYWNpbGl0YXRlIHRoaXMKcHJvY2Vzcy4KCiFbXShpbWcvaW1wb3J0LWRhdGEucG5nKQoKIyMjIyBbKipZb3VyIFR1cm4qKl17c3R5bGU9ImNvbG9yOiBncmVlbjsifSAqKuKktSoqCgpDb25zaWRlciB0aGUgZXhhbXBsZSBwaWN0dXJlZCBiZWxvdyBvZiBhIGRpc2N1c3Npb24gdGhyZWFkIGZyb20gdGhlClBsYW5uaW5nIGZvciB0aGUgRGlnaXRhbCBMZWFybmluZyBUcmFuc2l0aW9uIGluIEstMTIgU2Nob29scyAoRExUIDEpCndoZXJlIG91ciBkYXRhIG9yZ2luYXRlZC4gVGhpcyB0aHJlYWQgd2FzIGluaXRpYXRlZCBieSBwYXJ0aWNpcGFudCBJLCBzbwp0aGUgY29tbWVudHMgYnkgSiBhbmQgTiBhcmUgY29uc2lkZXJlZCB0byBiZSBkaXJlY3RlZCBhdCBJLiBUaGUgY29tbWVudApvZiBCLCBob3dldmVyLCBpcyBhIGRpcmVjdCByZXNwb25zZSB0byB0aGUgY29tbWVudCBieSBOIGFzIHNpZ25hbGVkIGJ5CnRoZSB1c2Ugb2YgdGhlIHF1b3RlLWZlYXR1cmUgYXMgd2VsbCBhcyB0aGUgZXhwbGljaXQgbWVudGlvbmluZyBvZiBOJ3MKbmFtZSB3aXRoaW4gQidzIGNvbW1lbnQuCgohW10oaW1nL2Rpc2N1c3Npb24tdGhyZWFkLnBuZykKCk5vdyBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMgYXMgdGhleSByZWxhdGUgdG8gdGhlIERMVCAxIGVkZ2UtbGlzdAp3ZSBqdXN0IHJlYWQgaW50byBSLgoKMS4gIFdoaWNoIGFjdG9ycyBpbiB0aGlzIHRocmVhZCBhcmUgdGhlIGBTZW5kZXJgIGFuZCB0aGUgYFJlY2lldmVyYD8KICAgIFdoaWNoIGFjdG9yIGlzIGJvdGg/CgogICAgLSAgIAoKMi4gIEhvdyBtYW55IGR5YWRzIGFyZSBpbiB0aGlzIHRocmVhZD8gV2hpY2ggcGFpcnMgb2YgYWN0b3JzIGFyZSBkeWFkcz8KCiAgICAtICAgCgoqKlNpZGViYXI6KiogVW5mb3J0dW5hdGVseSwgdGhlc2UgdHlwZXMgb2YgbnVhbmNlcyBpbiBkaXNjdXNzaW9uIGZvcnVtCmRhdGEgYXMgaWxsdXN0cmF0ZWQgYnkgdGhpcyBzaW1wbGUgZXhhbXBsZSBhcmUgcmFyZWx5IGNhcHR1cmVkIHRocm91Z2gKYXV0b21hdGVkIGFwcHJvYWNoZXMgdG8gY29uc3RydWN0aW5nIG5ldHdvcmtzLiBGb3J0dW5hdGVseSwgdGhlIGRhdGFzZXQKeW91IGFyZSB3b3JraW5nIHdpdGggd2FzIGNhcmVmdWxseSByZXZpZXdlZCB0byB0cnkgYW5kIGNhcHR1cmUgbW9yZQphY2N1cmF0ZWx5IHRoZSBpbnRlbmRlZCByZWNpcGllbnRzIG9mIGVhY2ggcmVwbHkuCgojIyMgTm9kZSBBdHRyaWJ1dGVzCgpUaGUgc2Vjb25kIGZpbGUgaXMgd2UnbGwgYmUgdXNpbmcgdG8gaGVscCB1bmRlcnN0YW5kIG91dCBuZXR3b3JrIGFuZCB0aGUKYWN0b3JzIGludm9sdmVkIGNvbnRhaW5zIGFsbCB0aGUgbm9kZXMgb3IgYWN0b3JzIChpLmUuLCBwYXJ0aWNpcGFudHMgd2hvCnBvc3RlZCB0byB0aGUgZGlzY3Vzc2lvbiBmb3J1bSkgYXMgd2VsbCBhcyBzb21lIG9mIHRoZWlyIGF0dHJpYnV0ZXMgc3VjaAphcyBnZW5kZXIgYW5kIHllYXJzIG9mIGV4cGVyaWVuY2UgaW4gZWR1Y2F0aW9uLgoKQ2Fyb2x5biAoMjAxMykgbm90ZXMgdGhhdCBtb3N0IHNvY2lhbCBuZXR3b3JrIGFuYWx5c2VzIGluY2x1ZGUgdmFyaWFibGVzCnRoYXQgZGVzY3JpYmUgYXR0cmlidXRlcyBvZiBhY3RvcnMsIG9uZXMgdGhhdCBhcmUgZWl0aGVyIGNhdGVnb3JpY2FsCihlLmcuLCBzZXgsIHJhY2UsIGV0Yy4pIG9yIGNvbnRpbnVvdXMgaW4gbmF0dXJlIChlLmcuLCB0ZXN0IHNjb3JlcywKbnVtYmVyIG9mIHRpbWVzIGFic2VudCwgZXRjLikuIFRoZXNlIGF0dHJpYnV0ZXMgdGhhdCBjYW4gYmUgaW5jb3Jwb3JhdGVkCmludG8gYSBuZXR3b3JrIGdyYXBoIG9yIG1vZGVsIHRvIG1ha2luZyBpdCBtdWNoIG1vcmUgaW5mb3JtYXRpdmUgYW5kIGNhbgphaWQgaW4gdGVzdGluZyBvciBnZW5lcmF0aW5nIGh5cG90aGVzZXMuCgpUaGVzZSBhdHRyaWJ1dGUgdmFyaWFibGVzIGFyZSB0eXBpY2FsbHkgaW5jbHVkZWQgaW4gYSByZWN0YW5ndWxhciBhcnJheSwKb3IgZGF0YWZyYW1lLCB0aGF0IG1pbWljcyB0aGUgYWN0b3ItYnktYXR0cmlidXRlIHRoYXQgaXMgdGhlIGRvbWluYW50CmNvbnZlbnRpb24gaW4gc29jaWFsIHNjaWVuY2UsIGkuZS4gcm93cyByZXByZXNlbnQgY2FzZXMsIGNvbHVtbnMKcmVwcmVzZW50IHZhcmlhYmxlcywgYW5kIGNlbGxzIGNvbnNpc3Qgb2YgdmFsdWVzIG9uIHRob3NlIHZhcmlhYmxlcy4KCkFzIGFuZCBhc2lkZSwgQ2Fyb2x5biBhbHNvIHJlZmVycyB0byB0aGlzIGhpc3RvcmljYWwgcHJlZmVyZW5jZSBieQpyZXNlYXJjaGVycyBmb3IgImFjdG9yLWJ5LWF0dHJpYnV0ZSIgZGF0YSwgaW4gdGhlIGFic2VuY2Ugb2YgcmVsYXRpb25hbApkYXRhIGluIHdoaWNoIHRoZSBhY3RvciBoYXMgYmVlbiByZW1vdmVkIHRoZWlyIHNvY2lhbCBjb250ZXh0LCBhcyB0aGUKInNvY2lvbG9naWNhbCBtZWF0Z3JpbmRlciIgaW4gYWN0aW9uLiBTcGVjaWZpY2FsbHksIHRoaXMgaGlzdG9yaWNhbAphcHByb2FjaCBhc3N1bWVzIHRoYXQgdGhlIGFjdG9yIGRvZXMgbm90IGludGVyYWN0IHdpdGggYW55b25lIGVsc2UgaW4KdGhlIHN0dWR5IGFuZCB0aGF0IG91dGNvbWVzIGFyZSBzb2xlbHkgZGVwZW5kZW50IG9mIHRoZSBjaGFyYWN0ZXJpc3RpY3MKb2YgdGhlIGluZGl2aWR1YWwuCgpSZWdhcmRsZXNzLCBsZXQncyByZWFkIGluIG91ciBub2RlIGF0dHJpYnV0ZSBmaWxlIGFuZCB0YWtlIGEgbG9vayBhdCB0aGUKYGFjdG9yc2AgYW5kIHRoZWlyIGF0dHJpYnV0ZXMgaW5jbHVkZWQgaW4gb3VyIGRhdGFzZXQ6CgpgYGB7cn0KYWN0b3JzIDwtIHJlYWRfY3N2KCJkYXRhL2RsdDEtbm9kZXMuY3N2IiwgCiAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKFVJRCA9IGNvbF9jaGFyYWN0ZXIoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhY2lsaXRhdG9yID0gY29sX2NoYXJhY3RlcigpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZXJ0ID0gY29sX2NoYXJhY3RlcigpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdCA9IGNvbF9jaGFyYWN0ZXIoKSkpCmBgYAoKIyMjIyBbKipZb3VyIFR1cm4qKl17c3R5bGU9ImNvbG9yOiBncmVlbjsifSAqKuKktSoqCgpVc2UgdGhlIGNvZGUgY2h1bmsgYmVsb3cgYW5kIGEgZnVuY3Rpb24gb2YgeW91ciBjaG9vc2luZyB0byB0YWtlIGEgbG9vawphdCB0aGUgYGFjdG9yc2AgZGF0YSBmcmFtZToKCmBgYHtyfQoKYGBgCgpNYXRjaCB1cCB0aGUgYXR0cmlidXRlcyBpbmNsdWRlZCBpbiB0aGUgbm9kZSBmaWxlIHdpdGggdGhlIGZvbGxvd2luZwpjb2RlYm9vayBkZXNjcmlwdG9ycy4gVGhlIGZpcnN0IG9uZSBoYXMgYmVlbiBkb25lIGFzIGFuIGV4YW1wbGUuCgotICAgYEZhY2lsaXRhdG9yYCA9IElkZW50aWZpY2F0aW9uIG9mIGNvdXJzZSBmYWNpbGl0YXRvciAoMSAqKj0qKgogICAgaW5zdHJ1Y3RvcikKLSAgIER1bW15IHZhcmlhYmxlIGZvciB3aGV0aGVyIHBhcnRpY2lwYW50cyBsaXN0ZWQKICAgIG5ldHdvcmtpbmcvY29sbGFib3JhdGlvbiB3aXRoIG90aGVycyBhcyBvbmUgb2YgdGhlaXIgY291cnNlIGdvYWxzIG9uCiAgICB0aGUgcmVnaXN0cmF0aW9uIGZvcm0KLSAgIElkZW50aWZpZXIgb2YgImV4cGVydCBwYW5lbGlzdHMiIGludml0ZWQgdG8gY291cnNlIHRvIHNoYXJlCiAgICBleHBlcmllbmNlIHRocm91Z2ggcmVjb3JkZWQgUSZBCi0gICBJZGVudGlmaWNhdGlvbiBvZiBjb3Vyc2UgZmFjaWxpdGF0b3IgKDEgKio9KiogaW5zdHJ1Y3RvcikKLSAgIFByb2Zlc3Npb25hbCByb2xlIChlZywgdGVhY2hlciwgbGlicmFyaWFuLCBhZG1pbmlzdHJhdG9yKQotICAgWWVhcnMgb2YgZXhwZXJpZW5jZSBhcyBhbiBlZHVjYXRvcgotICAgV29ya3Mgd2l0aCBlbGVtZW50YXJ5LCBtaWRkbGUsIGFuZC9vciBoaWdoIHNjaG9vbCBzdHVkZW50cwotICAgSW5pdGlhbCBhc3NpZ25tZW50IG9mIGRpc2N1c3Npb24gZ3JvdXAKCiMjIDJiLiBDcmVhdGUgYSBOZXR3b3JrIE9iamVjdAoKYGBge3J9Cm5ldHdvcmsgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGQ9dGllcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2VzPWFjdG9ycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkPVQpIAoKbmV0d29yawpgYGAK